package com.lz.ub.assist

import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Handler
import android.os.Looper
import android.os.Message
import com.felhr.usbserial.UsbSerialDevice
import com.felhr.usbserial.UsbSerialInterface.*
import com.lz.ub.Logger
import com.lz.ub.UBCDispatcher
import com.lz.ub.core.RFMainReader
import java.util.regex.Pattern

/**
 * @author You
 * 从设备调度器, 只能收发数据, 被动连接
 */
class UBCAssistDispatcher(
    private val usbManager: UsbManager,
    private val baudRate: Int,
    private val dataBits: Int,
    private val stopBits: Int,
    private val parity: Int,
    private val callback: UBCAssistCallback
) : Handler(Looper.getMainLooper()), UsbReadCallback, UsbCTSCallback, UsbDSRCallback {

    companion object {
        //最小响应长度
        private const val MIN_LEN = 2

        //连接
        private const val MSG_CONNECTED = 1

        //断开连接
        private const val MSG_DISCONNECTED = 2

        //收到消息
        private const val MSG_RECEIVED = 3

        //连接上的
        private const val CONNECTED = "CONNECTED"

                //断开
        private const val DISCONNECTED = "DISCONNECTED"

        //正则
        private val PATTERN = Pattern.compile("([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})")
    }

    //蓝牙设备绑定
    private var serialPort: UsbSerialDevice? = null

    //被动连接的设备
    private var connectedMac: String? = null

    //绑定的USB设备
    internal var usbDeviceId: Int = -1

    //是否已经打开
    fun isOpened(): Boolean = serialPort != null

    //是否可用
    fun isAvailable(): Boolean = isOpened() && connectedMac != null

    fun open(usbDevice: UsbDevice) {
        this.usbDeviceId = usbDevice.deviceId
        serialPort = openDevice(usbDevice)
    }

    fun close() {
        try {
            serialPort?.close()
        } catch (_: Exception) {
        }
        serialPort = null
        connectedMac = null
        this.usbDeviceId = -1
    }

    fun send(data: String): Boolean {
        if (isAvailable()) {
            serialPort?.write(data.toByteArray())
            return true
        }
        return false
    }

    private fun connected(mac: String) {
        this.connectedMac = mac
        callback.onConnected(mac)
    }

    private fun disconnected(mac: String) {
        this.connectedMac = null
        callback.onDisconnected(mac)
    }

    private fun openDevice(device: UsbDevice): UsbSerialDevice? {
        val serialPort = UsbSerialDevice.createUsbSerialDevice(device, usbManager.openDevice(device))
        if (serialPort.open()) {
            serialPort.setBaudRate(baudRate)
            serialPort.setDataBits(dataBits)
            serialPort.setStopBits(stopBits)
            serialPort.setParity(parity)
            serialPort.setFlowControl(FLOW_CONTROL_OFF)

            //上面是设置些常用参数
            serialPort.read(this)
            serialPort.getCTS(this)
            serialPort.getDSR(this)
            return serialPort
        }
        Logger.e(UBCDispatcher.TAG, "open err ************* ================= *************")
        return null
    }

    override fun handleMessage(msg: Message) {
        when (msg.what) {
            MSG_CONNECTED -> connected(msg.obj as String)
            MSG_DISCONNECTED -> disconnected(msg.obj as String)
            MSG_RECEIVED -> callback.onRead(msg.obj as String)
        }
    }

    override fun onReceivedData(data: ByteArray) {
        if (data.size <= MIN_LEN) {
            return
        }
        val str = String(data).trimEnd()
        Logger.d(RFMainReader.TAG, "-------------------------onReceiveData = $str")
        val matcher = PATTERN.matcher(str)
        if (matcher.find() && matcher.start() == 0) { //匹配到连上或者断开
            val mac = matcher.group()
            val end = matcher.end() + 1
            if (end < str.length) {
                val left = str.substring(end)
                if (left.startsWith(DISCONNECTED)) {
                    sendMessage(obtainMessage(MSG_DISCONNECTED, mac))
                } else if (left.startsWith(CONNECTED)) {
                    sendMessage(obtainMessage(MSG_CONNECTED, mac))
                }
            }
        } else {
            sendMessage(obtainMessage(MSG_RECEIVED, str))
        }
    }

    override fun onCTSChanged(state: Boolean) = Unit

    override fun onDSRChanged(state: Boolean) = Unit
}